﻿using AutoMapper;
using YDT_PaymentService.Applictions.DTOs;
using YDT_PaymentService.Applictions.Interfaces;
using YDT_PaymentService.Domain.Entities;
using YDT_PaymentService.Domain.Enums;
using YDT_PaymentService.Domain.Interfaces;

namespace YDT_PaymentService.Applictions.Services
{
    /// <summary>
    /// 支付应用服务实现 - 协调领域对象完成业务用例
    /// </summary>
    public class PaymentService : IPaymentService
    {
        private readonly IPaymentRepository _paymentRepository;
        private readonly IMapper _mapper;

        /// <summary>
        /// 构造函数 - 依赖注入
        /// </summary>
        public PaymentService(IPaymentRepository paymentRepository, IMapper mapper)
        {
            _paymentRepository = paymentRepository;
            _mapper = mapper;
        }

        /// <summary>
        /// 根据ID获取支付记录
        /// </summary>
        public async Task<PaymentDto?> GetPaymentByIdAsync(Guid id)
        {
            var payment = await _paymentRepository.GetByIdAsync(id);
            return _mapper.Map<PaymentDto>(payment);
        }

        /// <summary>
        /// 根据支付单号获取支付记录
        /// </summary>
        public async Task<PaymentDto?> GetPaymentByCodeAsync(string paymentCode)
        {
            var payment = await _paymentRepository.GetByPaymentCodeAsync(paymentCode);
            return _mapper.Map<PaymentDto>(payment);
        }

        /// <summary>
        /// 根据订单ID获取支付记录
        /// </summary>
        public async Task<PaymentDto?> GetPaymentByOrderIdAsync(Guid orderId)
        {
            var payment = await _paymentRepository.GetByOrderIdAsync(orderId);
            return _mapper.Map<PaymentDto>(payment);
        }

        /// <summary>
        /// 获取用户的所有支付记录
        /// </summary>
        public async Task<IEnumerable<PaymentDto>> GetPaymentsByUserIdAsync(Guid userId)
        {
            var payments = await _paymentRepository.GetByUserIdAsync(userId);
            return _mapper.Map<IEnumerable<PaymentDto>>(payments);
        }

        /// <summary>
        /// 获取所有支付记录
        /// </summary>
        public async Task<IEnumerable<PaymentDto>> GetAllPaymentsAsync()
        {
            var payments = await _paymentRepository.GetAllAsync();
            return _mapper.Map<IEnumerable<PaymentDto>>(payments);
        }

        /// <summary>
        /// 分页查询支付记录
        /// </summary>
        public async Task<(IEnumerable<PaymentDto> Payments, int TotalCount)> GetPagedPaymentsAsync(PaymentQueryDto query)
        {
            // 这里简化实现，实际项目中可能需要更复杂的查询逻辑
            var (payments, totalCount) = await _paymentRepository.GetPagedAsync(query.PageIndex, query.PageSize);
            var paymentDtos = _mapper.Map<IEnumerable<PaymentDto>>(payments);
            return (paymentDtos, totalCount);
        }

        /// <summary>
        /// 创建支付记录
        /// </summary>
        public async Task<PaymentDto> CreatePaymentAsync(CreatePaymentDto createPaymentDto)
        {
            // 检查订单是否已有支付记录
            var existingPayment = await _paymentRepository.GetByOrderIdAsync(createPaymentDto.OrderId);
            if (existingPayment != null &&
                (existingPayment.PaymentStatus == PaymentStatus.Pending ||
                 existingPayment.PaymentStatus == PaymentStatus.Initialized))
            {
                throw new InvalidOperationException($"订单 '{createPaymentDto.OrderId}' 已有待支付的支付记录");
            }

            // 创建支付实体
            var payment = new Payment(
                createPaymentDto.OrderId,
                createPaymentDto.UserId,
                createPaymentDto.PaymentPrice,
                createPaymentDto.PaymentType,
                createPaymentDto.PaymentMethod,
                createPaymentDto.PaymentReturnUrl,
                createPaymentDto.PaymentRemark
            );

            // 保存到数据库
            await _paymentRepository.AddAsync(payment);

            return _mapper.Map<PaymentDto>(payment);
        }

        /// <summary>
        /// 更新支付记录
        /// </summary>
        public async Task<PaymentDto?> UpdatePaymentAsync(Guid id, UpdatePaymentDto updatePaymentDto)
        {
            var payment = await _paymentRepository.GetByIdAsync(id);
            if (payment == null) return null;

            // 更新支付信息
            payment.UpdatePaymentInfo(
                updatePaymentDto.PaymentPrice,
                updatePaymentDto.PaymentMethod,
                updatePaymentDto.PaymentRemark
            );

            // 保存到数据库
            await _paymentRepository.UpdateAsync(payment);

            return _mapper.Map<PaymentDto>(payment);
        }

        /// <summary>
        /// 删除支付记录
        /// </summary>
        public async Task<bool> DeletePaymentAsync(Guid id)
        {
            var payment = await _paymentRepository.GetByIdAsync(id);
            if (payment == null) return false;

            // 只有特定状态的支付记录才能删除
            if (payment.PaymentStatus == PaymentStatus.Success ||
                payment.PaymentStatus == PaymentStatus.Refunded)
            {
                throw new InvalidOperationException("支付成功或已退款的记录不能删除");
            }

            await _paymentRepository.DeleteAsync(id);
            return true;
        }

        /// <summary>
        /// 初始化支付
        /// </summary>
        public async Task<PaymentDto?> InitializePaymentAsync(Guid id, InitializePaymentDto initializeDto)
        {
            var payment = await _paymentRepository.GetByIdAsync(id);
            if (payment == null) return null;

            payment.InitializePayment(initializeDto.PaymentUrl);
            await _paymentRepository.UpdateAsync(payment);

            return _mapper.Map<PaymentDto>(payment);
        }

        /// <summary>
        /// 处理支付成功
        /// </summary>
        public async Task<PaymentDto?> ProcessPaymentSuccessAsync(string paymentCode)
        {
            var payment = await _paymentRepository.GetByPaymentCodeAsync(paymentCode);
            if (payment == null) return null;

            payment.ProcessSuccess();
            await _paymentRepository.UpdateAsync(payment);

            return _mapper.Map<PaymentDto>(payment);
        }

        /// <summary>
        /// 处理支付失败
        /// </summary>
        public async Task<PaymentDto?> ProcessPaymentFailureAsync(string paymentCode, string errorNo, string errorInfo)
        {
            var payment = await _paymentRepository.GetByPaymentCodeAsync(paymentCode);
            if (payment == null) return null;

            payment.ProcessFailure(errorNo, errorInfo);
            await _paymentRepository.UpdateAsync(payment);

            return _mapper.Map<PaymentDto>(payment);
        }

        /// <summary>
        /// 取消支付
        /// </summary>
        public async Task<PaymentDto?> CancelPaymentAsync(Guid id)
        {
            var payment = await _paymentRepository.GetByIdAsync(id);
            if (payment == null) return null;

            payment.Cancel();
            await _paymentRepository.UpdateAsync(payment);

            return _mapper.Map<PaymentDto>(payment);
        }

        /// <summary>
        /// 开始退款流程
        /// </summary>
        public async Task<PaymentDto?> StartRefundAsync(Guid id)
        {
            var payment = await _paymentRepository.GetByIdAsync(id);
            if (payment == null) return null;

            payment.StartRefund();
            await _paymentRepository.UpdateAsync(payment);

            return _mapper.Map<PaymentDto>(payment);
        }

        /// <summary>
        /// 处理退款成功
        /// </summary>
        public async Task<PaymentDto?> ProcessRefundSuccessAsync(Guid id)
        {
            var payment = await _paymentRepository.GetByIdAsync(id);
            if (payment == null) return null;

            payment.ProcessRefund();
            await _paymentRepository.UpdateAsync(payment);

            return _mapper.Map<PaymentDto>(payment);
        }

        /// <summary>
        /// 处理退款失败
        /// </summary>
        public async Task<PaymentDto?> ProcessRefundFailureAsync(Guid id, string errorNo, string errorInfo)
        {
            var payment = await _paymentRepository.GetByIdAsync(id);
            if (payment == null) return null;

            payment.ProcessRefundFailed(errorNo, errorInfo);
            await _paymentRepository.UpdateAsync(payment);

            return _mapper.Map<PaymentDto>(payment);
        }
    }
}
